package com.jemframework.utils.stringformatter;

import java.util.ArrayList;
import java.util.List;

public abstract class AbstractStringFormatter implements StringFormatter {

  public String formatString(StringFormat anOriginalStringFormat, String aString) {
    StringFormatterFactory theFactory = StringFormatterFactory.getInstance();
    AbstractStringFormatter theOriginalStringFormatter = (AbstractStringFormatter) theFactory.getStringFormatter(anOriginalStringFormat);
    String[] theTokens = theOriginalStringFormatter.tokenizeString(aString);
    String theFormattedString = generateString(theTokens);
    return theFormattedString;
  }

  /**
   * Splits <code>aString</code> into 'lowercased' tokens.
   * 
   * @param aString
   * @return
   */
  protected String[] tokenizeString(String aString) {

    List<String> tokens = new ArrayList<String>();
    Integer[] positions = getTokensStartPositions(aString);

    for (int i = 0; i < positions.length; i++) {
      int start = positions[i];
      int end = computeEndPosition(i, positions, aString);

      String token = aString.substring(start, end);
      token = token.toLowerCase();
      tokens.add(token);
    }

    return tokens.toArray(new String[tokens.size()]);
  }

  public String generateString(String[] tokens) {

    StringBuffer buff = new StringBuffer();

    for (int i = 0; i < tokens.length; i++) {
      String token = tokens[i];
      formatToken(buff, token, tokens.length, i);
    }

    return buff.toString();
  }

  protected abstract void formatToken(StringBuffer out, String token, int tokens, int index);

  protected abstract Integer[] getTokensStartPositions(String string);

  protected abstract int computeEndPosition(int i, Integer[] positions, String string);

}
